import base64
import time, pandas as pd
import numpy as np
import jqdatasdk
import requests

import matplotlib
import re
import json
from bs4 import BeautifulSoup

from selenium import webdriver
matplotlib.use('Agg')

from django.contrib.auth import models as auth_models
from django.core.mail import send_mail

from Library_WEB import settings
from stocksys.tasks_function.serialization_data import serialization_data
from stocksys import models as stocksys_models
import datetime
from managersys import models as managersys_models


def send_email_message(title, content, to_email_list, type="TEXT"):
    # subject = '急速拉升提醒'  # 主题
    subject = title  # 主题
    message = content  # 内容
    sender = settings.EMAIL_FROM  # 发送邮箱
    receiver = to_email_list  # 目标邮箱
    html_message = content  # 发送html格式
    if type == "TEXT":
        send_mail(subject, message, sender, receiver, fail_silently=False)
    elif type == "HTML":
        send_mail(subject, message, sender, receiver, html_message=html_message, fail_silently=False)


def send_mobile_message(account, password, msg, phone):
    data = {"account": account,
            "password": password,
            "msg": "【253云通讯】您的验证码是2456",
            "params": "15800000000,张先生,1234;13800000000,李小姐,4321",
            "phone": phone,
            }
    url = 'http://smssh1.253.com/msg/variable/json'
    response = requests.post(url, data)


def init_message(request):
    context = dict()
    messages = []
    messages_orm = managersys_models.Message.objects.filter(recive_user=request.session.get("id"))
    for message in messages_orm:
        if not message.is_read:
            messages.append({
                'id': message.id,
                'create_time': message.create_time,
                'title': message.title,
            })
    context['head_messages'] = messages
    context['messages_num'] = messages_orm.filter(is_read=False).count()
    return context


def send_message_submit(from_user: auth_models.User, to_user: auth_models.User, title, content):
    from_user_id = from_user.id
    to_user_id = to_user.id
    managersys_models.Message.objects.create(send_user=from_user_id,
                                             recive_user=to_user_id,
                                             title=title,
                                             content=content,
                                             )


def get_day_exchange_time():
    '''
    获取昨日交易时间段
    :param date:
    :return: start_time end_time
    '''
    start_time = datetime.datetime.now() + datetime.timedelta(days=-7)
    end_time = datetime.datetime.now()
    return start_time.strftime("%Y-%m-%d"), end_time.strftime("%Y-%m-%d")


def get_month_exchange_time():
    '''
    获取上个月交易时间段
    :param date:
    :return: start_time end_time
    '''
    start_time = datetime.datetime.now() + datetime.timedelta(days=-30)
    end_time = datetime.datetime.now()
    return start_time.strftime("%Y-%m-%d"), end_time.strftime("%Y-%m-%d")


def get_yestoday():
    return (datetime.datetime.now() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d")


def resources2infojson(resources, display_name, method="JQDATA"):
    if type(resources) == type(None):
        return None
    if method == "JQDATA":
        resources['date'] = resources.index
    rows, cols = resources.shape
    resources.index = [x for x in range(rows)]
    data = []
    for row in range(rows):
        _row = resources.loc[row, :]
        timeStruct = time.strptime(str(_row['date'].to_pydatetime()), "%Y-%m-%d %H:%M:%S")
        _row_date = str(time.strftime("%Y-%m-%d", timeStruct))
        _row_open = float(_row['open'])
        _row_high = float(_row['high'])
        _row_close = float(_row['close'])
        _row_low = float(_row['low'])
        _row_volume = float(_row['money'])
        _row_volume_num = float(_row['volume'])
        # 数据模型 time0 open1 close2 min3 max4 vol5 tag6 macd7 dif8 dea9
        data.append([_row_date, _row_open, _row_close, _row_low, _row_high, _row_volume, 1, 0.04, 0.11, 0.09])
    info = {"stock_name": display_name, "statue": 200, "data": data}
    return info


def getResourceBySpider(code, start_year):
    now_year = int(time.strftime('%Y', time.localtime(time.time())))
    now_quarter = int(time.strftime('%m', time.localtime(time.time()))) // 4 + 1
    max_quarter = 4
    if now_year < int(start_year):
        raise Exception({"statue": 500, "data": [], "error": "now year < input year"})
    elif now_year == int(start_year):
        max_quarter = now_quarter
    stock_name, resources = serialization_data(code, start_year, 1)
    for quarter in range(2, max_quarter + 1):
        t_name, t_resources = serialization_data(code, start_year, quarter)
        resources = pd.concat([resources, t_resources], axis=0, ignore_index=True)
    resources.sort_values(by="date")
    return resources, stock_name


def getExchangeInfo(code, type, addr):
    '''
    获取交易类型信息
    :param code:
    :param type:
    :return:
    '''
    exchange = dict()
    exchange_info = dict()
    if type == "stock":
        exchange_address = stocksys_models.ExchangeAddress.objects.get(id=addr)
        exchange_info = stocksys_models.Stock.objects.get(code=code, exchange_address=exchange_address)
        exchange = {"type": type,
                    "address": exchange_info.exchange_address.id,
                    "address_name": exchange_info.exchange_address.stock_address_name,
                    "start_date": exchange_info.start_date,
                    "end_date": exchange_info.end_date,
                    "code": exchange_info.code,
                    "name": exchange_info.name,
                    "abbreviated_name": exchange_info.abbreviated_name,
                    }
    if type == "fund":
        exchange_address = stocksys_models.ExchangeAddress.objects.get(id=addr)
        exchange_info = stocksys_models.Fund.objects.get(code=code, exchange_address=exchange_address)
        exchange = {"type": type,
                    "address": exchange_info.exchange_address.id,
                    "address_name": exchange_info.exchange_address.stock_address_name,
                    "start_date": exchange_info.start_date,
                    "end_date": exchange_info.end_date,
                    "code": exchange_info.code,
                    "name": exchange_info.name,
                    }
    if type == "market_index":
        exchange_address = stocksys_models.ExchangeAddress.objects.get(id=addr)
        exchange_info = stocksys_models.MarketIndex.objects.get(code=code,
                                                                exchange_address=exchange_address)
        exchange = {"type": type,
                    "address": exchange_info.exchange_address.id,
                    "address_name": exchange_info.exchange_address.stock_address_name,
                    "start_date": exchange_info.start_date,
                    "end_date": exchange_info.end_date,
                    "code": exchange_info.code,
                    "name": exchange_info.name,
                    }
    if type == "industry":
        exchange_info = stocksys_models.Industry.objects.get(code=code)
        exchange = {"type": type,
                    "start_date": exchange_info.start_date,
                    "code": exchange_info.code,
                    "name": exchange_info.name,
                    }
    if type == "conceptual":
        exchange_info = stocksys_models.Concept.objects.get(code=code)
        exchange = {"type": type,
                    "start_date": exchange_info.start_date,
                    "code": exchange_info.code,
                    "name": exchange_info.name,
                    }
    return exchange


def getStockChgByJqdata(stock: stocksys_models.Stock):
    jqdata_code = stock.code + '.' + stock.exchange_address.stock_jqdata_name

    # 昨天
    start_date = datetime.datetime.now() + datetime.timedelta(days=-7)
    start_date = start_date.strftime("%Y-%m-%d")

    # 今天
    end_date = datetime.datetime.now()
    end_date = end_date.strftime("%Y-%m-%d")

    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)
    data = jqdatasdk.get_price(jqdata_code, start_date=start_date, end_date=end_date, frequency='daily',
                               fields=None,
                               skip_paused=False, fq='pre')
    jqdatasdk.logout()

    data['date'] = data.index
    data.index = [x for x in range(len(data))]
    # 涨跌额=(当前价格-昨日收盘)
    today_close = data.loc[1]['close']
    yestoday_close = data.loc[0]['close']
    chg = (today_close - yestoday_close)
    if np.isnan(chg):
        return None
    # 涨跌幅=(当前价格-昨日收盘)/当前价格*100
    pchg = (chg / today_close) * 100
    # 成交额
    money = data.loc[1]['money'] / 10000
    # 成交量
    volume = data.loc[1]['volume'] / 10000
    price = today_close
    color = ''
    if chg < 0:
        color = 'success'
    elif chg > 0:
        color = 'danger'
    return {'name': stock.name,
            'code': stock.code,
            'chg': chg,
            'money': money,
            'volume': volume,
            'pchg': pchg,
            'price': price,
            'color': color,
            }


def getFundChgByJqdata(fund: stocksys_models.Fund):
    jqdata_code = fund.code + '.' + fund.exchange_address.stock_jqdata_name

    # 昨天
    start_date = datetime.datetime.now() + datetime.timedelta(days=-7)
    start_date = start_date.strftime("%Y-%m-%d")

    # 今天
    end_date = datetime.datetime.now()
    end_date = end_date.strftime("%Y-%m-%d")
    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)
    data = jqdatasdk.get_price(jqdata_code, start_date=start_date, end_date=end_date, frequency='daily',
                               fields=None,
                               skip_paused=False, fq='pre')
    jqdatasdk.logout()
    data['date'] = data.index
    data.index = [x for x in range(len(data))]

    # 涨跌额=(当前价格-昨日收盘)
    chg = (data.loc[1]['close'] - data.loc[0]['close'])
    if np.isnan(chg):
        return None
    # 涨跌幅=(当前价格-昨日收盘)/当前价格*100
    pchg = (chg / data.loc[1]['close']) * 100
    # 成交额
    money = data.loc[1]['money'] / 10000
    # 成交量
    volume = data.loc[1]['volume'] / 10000
    price = data.loc[1]['close']
    color = ''
    if chg < 0:
        color = 'success'
    elif chg > 0:
        color = 'danger'
    return {'name': fund.name,
            'code': fund.code,
            'chg': chg,
            'money': money,
            'volume': volume,
            'pchg': pchg,
            'price': price,
            'color': color,
            }


def getMarketIndexChgByJqdata(market_index: stocksys_models.MarketIndex):
    jqdata_code = market_index.code + '.' + market_index.exchange_address.stock_jqdata_name

    # 昨天
    start_date = datetime.datetime.now() + datetime.timedelta(days=-7)
    start_date = start_date.strftime("%Y-%m-%d")

    # 今天
    end_date = datetime.datetime.now()
    end_date = end_date.strftime("%Y-%m-%d")
    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)
    data = jqdatasdk.get_price(jqdata_code, start_date=start_date, end_date=end_date, frequency='daily',
                               fields=None,
                               skip_paused=False, fq='pre')
    jqdatasdk.logout()
    data['date'] = data.index
    data.index = [x for x in range(len(data))]
    # 涨跌额=(当前价格-昨日收盘)
    chg = (data.loc[1]['close'] - data.loc[0]['close'])
    if np.isnan(chg):
        return None
    # 涨跌幅=(当前价格-昨日收盘)/当前价格*100
    pchg = (chg / data.loc[1]['close']) * 100
    # 成交额
    money = data.loc[1]['money'] / 10000
    # 成交量
    volume = data.loc[1]['volume'] / 10000
    price = data.loc[1]['close']
    color = ''
    if chg < 0:
        color = 'success'
    elif chg > 0:
        color = 'danger'
    return {'name': market_index.code,
            'code': market_index.code,
            'chg': chg,
            'money': money,
            'volume': volume,
            'pchg': pchg,
            'price': price,
            'color': color,
            }


def get_stock_json_info(stock: stocksys_models.Stock):
    now_date = time.strftime('%Y-%m-%d', time.localtime(time.time()))
    now_year = str(time.strftime('%Y', time.localtime(time.time())))
    info = {"statue": 500, "data": []}
    if settings.USE_JQDATA_SDK:
        api_keys = stocksys_models.APIKeys.objects.all().first()
        jqdatasdk.auth(api_keys.username, api_keys.password)
        security = jqdatasdk.get_security_info("%s.%s" % (stock.code, stock.exchange_address.stock_jqdata_name))

        resources = jqdatasdk.get_price(security, start_date=now_year + '-01-01', end_date=now_date,
                                        frequency='daily',
                                        fields=None,
                                        skip_paused=False, fq='pre')
        info = resources2infojson(resources, security.display_name)
        jqdatasdk.logout()
    else:
        # TODO:不使用JQDATA数据平台
        resources, stock_name = getResourceBySpider(stock.code, start_year=now_year)
        info = resources2infojson(resources, stock_name, None)
    return info


def get_market_index_json_info(market_index: stocksys_models.MarketIndex):
    now_date = datetime.datetime.now()
    delta = datetime.timedelta(days=-100)
    start_date = now_date + delta

    info = {"statue": 500, "data": []}
    if settings.USE_JQDATA_SDK:
        api_keys = stocksys_models.APIKeys.objects.all().first()

        jqdatasdk.auth(api_keys.username, api_keys.password)

        security = jqdatasdk.get_security_info(
            "%s.%s" % (market_index.code, market_index.exchange_address.stock_jqdata_name))
        resources = jqdatasdk.get_price(start_date=start_date,
                                   end_date=now_date,
                                   security=security,
                                   frequency='daily',
                                   skip_paused=True,
                                   fq='pre')
        # resources = jqdatasdk.attribute_history_engine(end_dt=now_date, count=365, security=security, unit='1d',
        #                                                fields=('open', 'close', 'high', 'low', 'volume', 'money'),
        #                                                skip_paused=True,
        #                                                df=True, fq=None)
        info = resources2infojson(resources, security.display_name)
        jqdatasdk.logout()

    else:
        pass
        # resources, stock_name = getResourceBySpider(market_index.code, start_year=now_year,
        #                                             type="market_index")
        # info = resources2infojson(resources, stock_name, None)
    return info


def get_one_day_call_auction(stock: stocksys_models.Stock):
    jqdata_code = "%s.%s" % (stock.code, stock.exchange_address.stock_jqdata_name)
    start_date, end_date = get_day_exchange_time()
    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)

    call_auction = jqdatasdk.get_call_auction(jqdata_code, start_date, end_date, fields=None)
    call_auction = [call_auction.loc[index].to_dict() for index in range(len(call_auction))]

    jqdatasdk.logout()
    return call_auction[-1] if len(call_auction) >= 1 else call_auction


def get_one_day_mtss(stock):
    jqdata_code = "%s.%s" % (stock.code, stock.exchange_address.stock_jqdata_name)
    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)
    start_date, end_date = get_month_exchange_time()
    mtss = jqdatasdk.get_mtss(jqdata_code, start_date, end_date)
    mtss = [mtss.loc[index].to_dict() for index in range(len(mtss))]
    jqdatasdk.logout()

    return mtss[-5:] if len(mtss) >= 5 else mtss


def get_query_count():
    api_keys = stocksys_models.APIKeys.objects.all().first()
    jqdatasdk.auth(api_keys.username, api_keys.password)
    count = jqdatasdk.get_query_count()
    jqdatasdk.logout()
    return count


def get_stock_company_info(stock: stocksys_models.Stock):
    stock_code = "%s%s" % (stock.exchange_address.stock_sina_name, stock.code)

    url = "https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpInfo/stockid/"+ str(stock_code)+".phtml"
    # 爬虫
    response = requests.get(url=url).content.decode('gbk')
    soup = BeautifulSoup(response, "html.parser")
    col = soup.find(id="comInfo1").find_all("td")
    a = []
    for i in col:
        a.append(i.get_text())
    info = {
      'company_name': a[1],
      'company_english_name': a[3],
      'listed_market': a[5], #上市市场/
      'launch_date': a[7], #上市日期
      'offering_price': a[9], #发行价格
      'lead_underwriter': a[11], #主承销商
      'setup_date': a[13], #成立日期
      'registered_capital': a[15], #注册资本
      'body_type': a[17], #机构类型
      'organizational_form': a[19], #组织形式
      'board_secretary': a[21], #董事会秘书
      'phone_company': a[23], #公司电话
      'chairman_secretary_phone': a[25], #董秘电话
      'company_fax': a[27], #公司传真
      'chairman_fax': a[29], #董秘传真
      'company_e_mail': a[31], #公司电子邮箱
      'chairman_email_address': a[33], #董秘电子邮箱
      'company_web_site': a[35], #公司网址
      'zip_code': a[37], #邮政编码
      'registered_address': a[43], #注册地址
      'office_address': a[45] #办公地址/
    }
    return info



import numpy as np
import pandas as pd
import matplotlib.pyplot as plt


def frequency_analysis(data, freq_start=1, freq_end=lambda x: int(x / 2)):
    from matplotlib import style
    import matplotlib.pyplot as plt
    from io import BytesIO
    close = data['close'].values
    data_length = len(close)
    close_fft = np.fft.fft(close)
    close_fft_normal = np.abs(close_fft) / (len(close_fft) / 2)
    indexf = np.arange(len(close_fft_normal))

    if freq_end is None and freq_start is not None:
        close_fft_normal = close_fft_normal[freq_start:]
        indexf = indexf[freq_start:]
    elif freq_start is None and freq_end is not None:
        close_fft_normal = close_fft_normal[: freq_end(data_length)]
        indexf = indexf[:, freq_end(data_length)]
    else:
        print(len(close_fft_normal), freq_start, freq_end(data_length))
        close_fft_normal = close_fft_normal[freq_start: freq_end(data_length)]
        indexf = indexf[freq_start: freq_end(data_length)]

    style.use('ggplot')
    plt.plot(indexf, close_fft_normal)
    save_file = BytesIO()
    plt.savefig(save_file, format='png')
    image_base64 = base64.b64encode(save_file.getvalue()).decode('utf8')
    plt.show()
    save_file.close()
    plt.close()
    return image_base64
